{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# OpenBabel Interface\n",
    "\n",
    "In this tutorial we will demonstrate how `molli` `Molecule` objects can be efficiently converted into `openbabel` objects.\n",
    "\n",
    "Note: `openbabel` is not natively installed within Molli, but it can be added through conda using the line:\n",
    "`conda install openbabel`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Imports molli\n",
    "import molli as ml\n",
    "\n",
    "#Imports the Openbabel\n",
    "from openbabel import openbabel as ob\n",
    "\n",
    "#Imports molli interface with openbabel for additional functionality\n",
    "from molli.external import openbabel as mob\n",
    "ml.visual.configure(bgcolor='white')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following cell shows a conversion of an example molecule into openbabel `OBMol` object"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#This loads the Molli molecule object\n",
    "ml_mol = ml.load(ml.files.dendrobine_mol2)\n",
    "\n",
    "#This creates an instance of an OBMol object\n",
    "obmol = mob.to_obmol(ml_mol)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's make sure that what we get out of that operation is a valid `OBMol` object by converting it into a human readable representation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "@<TRIPOS>MOLECULE\n",
      "dendrobine\n",
      " 44 47 0 0 0\n",
      "SMALL\n",
      "GASTEIGER\n",
      "\n",
      "@<TRIPOS>ATOM\n",
      "      1 N           1.2960   -0.2319    1.2670 N.3     1  UNL1       -0.2981\n",
      "      2 C           0.0573   -0.0226    2.1227 C.3     1  UNL1        0.0024\n",
      "      3 C          -1.0974   -0.4738    1.2059 C.3     1  UNL1       -0.0210\n",
      "      4 C          -0.4284   -0.4113   -0.1687 C.3     1  UNL1       -0.0055\n",
      "      5 C           0.8683    0.3598   -0.0004 C.3     1  UNL1        0.0534\n",
      "      6 C           2.4562    0.4417    1.8361 C.3     1  UNL1       -0.0123\n",
      "      7 C          -2.4328    0.2659    0.9832 C.3     1  UNL1       -0.0482\n",
      "      8 C          -2.6553    0.2472   -0.5801 C.3     1  UNL1       -0.0486\n",
      "      9 C          -1.2428    0.5626   -1.0163 C.3     1  UNL1       -0.0205\n",
      "     10 C           1.5353    0.5790   -1.4179 C.3     1  UNL1        0.1228\n",
      "     11 O           1.3410    2.0363   -1.6507 O.3     1  UNL1       -0.4592\n",
      "     12 C           0.0782    2.2291   -2.2166 C.2     1  UNL1        0.3112\n",
      "     13 C          -0.5977    0.8539   -2.4020 C.3     1  UNL1        0.0662\n",
      "     14 O          -0.4135    3.3180   -2.4552 O.2     1  UNL1       -0.2505\n",
      "     15 C           0.7602    0.1678   -2.7001 C.3     1  UNL1        0.0132\n",
      "     16 C           0.7812   -1.2141   -3.3773 C.3     1  UNL1       -0.0397\n",
      "     17 H           1.2426    0.7684   -3.4982 H       1  UNL1        0.0347\n",
      "     18 H          -1.1794    1.5580   -0.5377 H       1  UNL1        0.0315\n",
      "     19 H           0.6516    1.3952    0.3174 H       1  UNL1        0.0504\n",
      "     20 H          -1.3722   -1.4910    1.5134 H       1  UNL1        0.0319\n",
      "     21 C          -0.2828   -1.8835   -0.5957 C.3     1  UNL1       -0.0574\n",
      "     22 C           2.1775   -1.8412   -3.3215 C.3     1  UNL1       -0.0623\n",
      "     23 C           0.3485   -1.1006   -4.8514 C.3     1  UNL1       -0.0623\n",
      "     24 H           0.0590   -1.9009   -2.9478 H       1  UNL1        0.0300\n",
      "     25 H          -0.0649    1.0264    2.4198 H       1  UNL1        0.0429\n",
      "     26 H           0.1162   -0.6408    3.0244 H       1  UNL1        0.0429\n",
      "     27 H           2.7150   -0.0049    2.8019 H       1  UNL1        0.0391\n",
      "     28 H           2.2927    1.5147    1.9874 H       1  UNL1        0.0391\n",
      "     29 H           3.3255    0.3162    1.1818 H       1  UNL1        0.0391\n",
      "     30 H          -2.3716    1.2962    1.3534 H       1  UNL1        0.0269\n",
      "     31 H          -3.2639   -0.2261    1.4982 H       1  UNL1        0.0269\n",
      "     32 H          -3.3810    1.0069   -0.8836 H       1  UNL1        0.0268\n",
      "     33 H          -2.9934   -0.7358   -0.9222 H       1  UNL1        0.0268\n",
      "     34 H           2.6088    0.3798   -1.4394 H       1  UNL1        0.0753\n",
      "     35 H          -1.2929    0.8772   -3.2423 H       1  UNL1        0.0420\n",
      "     36 H          -0.3075   -2.5854    0.2475 H       1  UNL1        0.0236\n",
      "     37 H           0.6920   -2.0890   -1.0319 H       1  UNL1        0.0236\n",
      "     38 H          -1.0943   -2.1904   -1.2614 H       1  UNL1        0.0236\n",
      "     39 H           2.1795   -2.8241   -3.8049 H       1  UNL1        0.0232\n",
      "     40 H           2.5176   -1.9822   -2.2914 H       1  UNL1        0.0232\n",
      "     41 H           2.9143   -1.2135   -3.8343 H       1  UNL1        0.0232\n",
      "     42 H           0.3522   -2.0859   -5.3307 H       1  UNL1        0.0232\n",
      "     43 H           1.0232   -0.4520   -5.4210 H       1  UNL1        0.0232\n",
      "     44 H          -0.6652   -0.6967   -4.9346 H       1  UNL1        0.0232\n",
      "@<TRIPOS>BOND\n",
      "     1    43    23    1\n",
      "     2    42    23    1\n",
      "     3    44    23    1\n",
      "     4    23    16    1\n",
      "     5    41    22    1\n",
      "     6    39    22    1\n",
      "     7    17    15    1\n",
      "     8    16    22    1\n",
      "     9    16    24    1\n",
      "    10    16    15    1\n",
      "    11    22    40    1\n",
      "    12    35    13    1\n",
      "    13    15    13    1\n",
      "    14    15    10    1\n",
      "    15    14    12    2\n",
      "    16    13    12    1\n",
      "    17    13     9    1\n",
      "    18    12    11    1\n",
      "    19    11    10    1\n",
      "    20    34    10    1\n",
      "    21    10     5    1\n",
      "    22    38    21    1\n",
      "    23    37    21    1\n",
      "    24     9     8    1\n",
      "    25     9    18    1\n",
      "    26     9     4    1\n",
      "    27    33     8    1\n",
      "    28    32     8    1\n",
      "    29    21     4    1\n",
      "    30    21    36    1\n",
      "    31     8     7    1\n",
      "    32     4     5    1\n",
      "    33     4     3    1\n",
      "    34     5    19    1\n",
      "    35     5     1    1\n",
      "    36     7     3    1\n",
      "    37     7    30    1\n",
      "    38     7    31    1\n",
      "    39    29     6    1\n",
      "    40     3    20    1\n",
      "    41     3     2    1\n",
      "    42     1     6    1\n",
      "    43     1     2    1\n",
      "    44     6    28    1\n",
      "    45     6    27    1\n",
      "    46     2    25    1\n",
      "    47     2    26    1\n",
      "\n"
     ]
    }
   ],
   "source": [
    "converter = ob.OBConversion()\n",
    "converter.SetInAndOutFormats(\"mol2\", \"mol2\")\n",
    "print(converter.WriteString(obmol))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Molli has built in wrappers that can interface within Openbabel. For example, an `ml_mol` object could be converted to a file format that is not natively available as an output within Molli, such as SDF or SMILES, using the `ml.dumps` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dendrobine\n",
      " OpenBabel10212414373D\n",
      "\n",
      " 44 47  0  0  1  0  0  0  0  0999 V2000\n",
      "    1.2960   -0.2319    1.2670 N   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    0.0573   -0.0226    2.1227 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -1.0974   -0.4738    1.2059 C   0  0  2  0  0  0  0  0  0  0  0  0\n",
      "   -0.4284   -0.4113   -0.1687 C   0  0  2  0  0  0  0  0  0  0  0  0\n",
      "    0.8683    0.3598   -0.0004 C   0  0  2  0  0  0  0  0  0  0  0  0\n",
      "    2.4562    0.4417    1.8361 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -2.4328    0.2659    0.9832 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -2.6553    0.2472   -0.5801 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -1.2428    0.5626   -1.0163 C   0  0  2  0  0  0  0  0  0  0  0  0\n",
      "    1.5353    0.5790   -1.4179 C   0  0  2  0  0  0  0  0  0  0  0  0\n",
      "    1.3410    2.0363   -1.6507 O   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    0.0782    2.2291   -2.2166 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -0.5977    0.8539   -2.4020 C   0  0  1  0  0  0  0  0  0  0  0  0\n",
      "   -0.4135    3.3180   -2.4552 O   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    0.7602    0.1678   -2.7001 C   0  0  2  0  0  0  0  0  0  0  0  0\n",
      "    0.7812   -1.2141   -3.3773 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    1.2426    0.7684   -3.4982 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -1.1794    1.5580   -0.5377 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    0.6516    1.3952    0.3174 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -1.3722   -1.4910    1.5134 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -0.2828   -1.8835   -0.5957 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    2.1775   -1.8412   -3.3215 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    0.3485   -1.1006   -4.8514 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    0.0590   -1.9009   -2.9478 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -0.0649    1.0264    2.4198 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    0.1162   -0.6408    3.0244 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    2.7150   -0.0049    2.8019 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    2.2927    1.5147    1.9874 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    3.3255    0.3162    1.1818 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -2.3716    1.2962    1.3534 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -3.2639   -0.2261    1.4982 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -3.3810    1.0069   -0.8836 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -2.9934   -0.7358   -0.9222 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    2.6088    0.3798   -1.4394 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -1.2929    0.8772   -3.2423 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -0.3075   -2.5854    0.2475 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    0.6920   -2.0890   -1.0319 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -1.0943   -2.1904   -1.2614 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    2.1795   -2.8241   -3.8049 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    2.5176   -1.9822   -2.2914 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    2.9143   -1.2135   -3.8343 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    0.3522   -2.0859   -5.3307 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "    1.0232   -0.4520   -5.4210 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "   -0.6652   -0.6967   -4.9346 H   0  0  0  0  0  0  0  0  0  0  0  0\n",
      "  1  6  1  0  0  0  0\n",
      "  1  2  1  0  0  0  0\n",
      "  2 25  1  0  0  0  0\n",
      "  2 26  1  0  0  0  0\n",
      "  3 20  1  1  0  0  0\n",
      "  3  2  1  0  0  0  0\n",
      "  4 21  1  6  0  0  0\n",
      "  4  5  1  0  0  0  0\n",
      "  4  3  1  0  0  0  0\n",
      "  5 19  1  1  0  0  0\n",
      "  5  1  1  0  0  0  0\n",
      "  6 28  1  0  0  0  0\n",
      "  6 27  1  0  0  0  0\n",
      "  7  3  1  0  0  0  0\n",
      "  7 30  1  0  0  0  0\n",
      "  7 31  1  0  0  0  0\n",
      "  8  7  1  0  0  0  0\n",
      "  9  8  1  0  0  0  0\n",
      "  9 18  1  1  0  0  0\n",
      "  9  4  1  0  0  0  0\n",
      " 10 34  1  6  0  0  0\n",
      " 10  5  1  0  0  0  0\n",
      " 11 10  1  0  0  0  0\n",
      " 12 11  1  0  0  0  0\n",
      " 13 35  1  6  0  0  0\n",
      " 13 12  1  0  0  0  0\n",
      " 13  9  1  0  0  0  0\n",
      " 14 12  2  0  0  0  0\n",
      " 15 17  1  6  0  0  0\n",
      " 15 13  1  0  0  0  0\n",
      " 15 10  1  0  0  0  0\n",
      " 16 22  1  0  0  0  0\n",
      " 16 24  1  0  0  0  0\n",
      " 16 15  1  0  0  0  0\n",
      " 21 36  1  0  0  0  0\n",
      " 22 40  1  0  0  0  0\n",
      " 23 16  1  0  0  0  0\n",
      " 29  6  1  0  0  0  0\n",
      " 32  8  1  0  0  0  0\n",
      " 33  8  1  0  0  0  0\n",
      " 37 21  1  0  0  0  0\n",
      " 38 21  1  0  0  0  0\n",
      " 39 22  1  0  0  0  0\n",
      " 41 22  1  0  0  0  0\n",
      " 42 23  1  0  0  0  0\n",
      " 43 23  1  0  0  0  0\n",
      " 44 23  1  0  0  0  0\n",
      "M  END\n",
      "$$$$\n",
      "\n",
      "N1(C[C@@H]2[C@@]3([C@@H]1[C@@H]1OC(=O)[C@H]([C@H]3CC2)[C@@H]1C(C)C)C)C\tdendrobine\n",
      "\n"
     ]
    }
   ],
   "source": [
    "sdf_str = ml.dumps(ml_mol, fmt='sdf', writer='openbabel')\n",
    "\n",
    "print(sdf_str)\n",
    "\n",
    "smi_str = ml.dumps(ml_mol, fmt='smi', writer='openbabel')\n",
    "\n",
    "print(smi_str)"
   ]
  },
  {
   "attachments": {
    "image.png": {
     "image/png": "iVBORw0KGgoAAAANSUhEUgAAAVUAAAGXCAYAAAADLMORAAAgAElEQVR4Ae2dP6gWSdbGDc2ukRgYDBdEAwODDxRxvc4IO+5uopnJLi4mTiaMgbAsBouYrcsgGBoIa7KzYiQbCZsIIhg6RmYaGhgY9sdzZ89r3bp1qqvrX3dVPw2Xfrvf6vrzO1VPVZ2qfu+BgQcJkAAJkEA2AgeyxcSISIAESIAEBooqKwEJkAAJZCRAUc0Ik1GRAAmQAEWVdYAESIAEMhKgqGaEyahIgARIgKLKOkACJEACGQlQVDPCZFQkQAIkQFFlHSABEiCBjAQoqhlhMioSIAESoKiyDpAACZBARgIU1YwwGRUJkAAJUFRZB0iABEggIwGKakaYjIoESIAEKKqsAyRAAiSQkQBFNSNMRkUCJEACFFXWARIgARLISICimhEmo2qfwKtXr4aPHz+2XxCWYDYCFNXZ0DPhJRGAkP7xj38ctre3h4MHDw537twZvnz5sqQsMi+NEKCozmColy9fDn/605/YcGdgbycJ4bx3795w6NCh4ezZs8OBAwc2f0eOHBkePXpkP8JrEvASoKh68eT9EqOhq1ev7jbaU6dO7Z7RcJ88eZI3IcYWROD58+fDN998s2uHnZ2djZiaworPsNWLFy+C4mQgEqCoVqgDMhrCtFIarIiqXF+4cGF48+ZNhdwwibdv3w6XLl3aYwvTNmIT+3z58uXh/fv3BEgCXgIUVS+e9C+fPn26GQ2ZjfTbb7/dNGrz/o0bN7hQko7dGcOnT5+G27dv7+F++PDhAX+mDXyfIb6IA3HxIAEXAYqqi0qGexh1YvRpN1D47uDDw+h1LEyGbDCK/xF4+PDhAFeLaQ8I5MmTJ/fcM7/3fUZciJMHCdgEKKo2kcRrjGAw2nQ1SPhTXdt1MJq1GzyeP3HixAC/H494AlgUPHPmzD57wJf6z3/+09nxuWyn3aO/Nd42vT5JUc1o2fv37++uItsNEI0ajdt3YOSKbTwu3x78f/AD8ggnYC4KmvYAX3u7lOaiMZ8b+0x/a7hteg9JUc1gYYwmMaq0G17Myr4mBoibvrxxY8miINwstj20mQJixXNap2jHo13T3zpunzWEoKgmWNleRZbGJo0LDTX20Kat9OXpRM0tUmILnKdM0eG+uXnz5j5BNuMb+0wb6TZawzcU1Qgru1aRpaHlnga6FlhEKMZcChFFa/IRrXNLETctTrFzyBliTp94k1UqKdMU1Yn4fCJXaoO4iLjL3+qb0k4sWnPBhYtL4DDaxPeph+bacaWp3aNPPNUKbT1PUQ20FwTT3rCPRgTfHXxxNQ5sPMdI2G68rsWXGvmZMw2tcyslYKn+Vtgsl9DPyZ1pjxOgqI4wwsKRS8hyNBLsU43xu2qjJ0x3sZLd86H5mrFFqnTZZWTsmjHYHZ12XbMT7rkeLLlsFFXFOhC7kluc0EAhgilioI2eenzlVdsVAYGTlykUU2a/rc0YNCF13ece5OxmWUyEFFWHKfADJxA8uzFAAHMtPNgrzLFCCHG245J84yWEHH5FB6Jqt9C5ya9ISbnkPLc/WXMJSf5CzqXcFdUMxIT2EaCoGki0qaX5aqkRPPojhEJzKcQKIVartddia/l8o4EoD6IDQ0dmixN82yV2PsS6DzT/rp1v3zX9rUolaPA2RXUYdl8d1V4txX1MPUscmm80xe+mvR3U0nRT286UskVqzH7wb0P0YjnR3zpGeD3fr1pUfVPLkFdLc1UTzTca28B95cJ0c6k/XyfC5BrRlR7J2Ts7Yvcba75fV5m0e7B77Kg5V51kPPEEViuq2ogOo6E5fjTa5xuN9buhgbtG4FjcWdorr9oUOrbsU5oE2LtcJymcNFeSJqSu+7F+9illZ9j8BFYnqtrUEg3I/qGN/LjHY9R8o2h0sUKoNfCS0+nxkv4aQstbzkXB0Lz4OtrYf6uiLXq6RFS7V9IFFcqG4cIJrEZUfSNBTPVK+U3DTbE3pK+BY1QXc2gNvKarQ/KtTZNzLwpKeqFnn+sklhPi1LbnaUJq35+bSyg/hhuGVYiq5rOEH63Uq6U5Kpevgcfm3dfAa2xR8pWpRvqhdtFEH2IXm0/Eee3atX27GWwB9V2n7GsOLTvDpRHoWlQhmHD625V0CdPeKWZDY3T5RlGulAUV17aukpvptS1SsSPAKQxjw2ruiRRO2n98sOup75r+1liLln+uS1H1vfES65csb4rxFHwNHOXCKHDqoW1gzzki0vzYLXVumuskhZPm4vGJqf0d/a1Ta3z58F2JqmzJwSjCrnw1VpHLm+vXFLQGnrJzQVt9TxkRiT1sW+C6xc7N5zqJ5eRzh7i4ue7R31qr5YWl042oYnUWomJXuti9nmH45gvla+Cx02mfCE7dJ6qJdA+dm28mhJEjOE49fC4eu05r1ymj5qn5ZXidQPOiqk2JpffWi97HNyUWVLTpOpiOvfKq2QMNPtfvJizFcprrJISTVgaNvSakrvuxnaqWJ96fRqBZUfWJyRr9TBAz+60gNLiUBRXtNVrX6F+zh3RuMf7eaVV5vtDaqNzFKTSXGnuXiGr3YncphOaR4dwEmhNV37Q31q/lRtPmXa2Bp0wNtS1p2D3wyy+/qL8ihe1DENs1HD7XCVwesa8Ga+w1ITXvb21t7e4OWQP/JZWxKVH9z3/+4/zVIvhSsZLK41cC0sBdC3axHQ/idG3rOnfu3D4/9pqnn9r0HbaIXZwDe+3nHU0RNT/v7OwMEFV0pjzqEmhKVP/whz/seUcbFXUJr5bWNVl4amMLKjGjSHuP5bfffrsRVXRusa9zhpeqjZDa9B2MMJuIOSDYrr3FppjCBXT8+PGNTSiqMaTTnmlKVDHKQgXa3t4e/vznP69maplm4mF3gcj1EoT4O2Pix8zg4sWLu/ZAQ/7xxx+jVr1j0m7pGW36njKady2QHT16dDh9+vRGTEVoKar1a0uToooKwxHR9MqiNfDYBRU0WGm8aOg83AQ01wnYpSwmYcR77Nix3dmby9WD+CmqbpuUvEtRLUl3gXH7/HNT95BSVKcZ2HadSIeU4saC+0vicZ0pqtNslCM0RTUHxQbj0BZU0DBDN/pTVOMMr72eCp5TF1wpqnE2KPkURbUk3QbixoKKKY4y2sGCytjeUvM5Tv+nGRtstX9oOGWHBkV1GvcaobsUVaxqo5HjD5viefgJuBo4GvzYQVEdIzT+vfbSBDq3kFdeKarjjGuH6FJUsYglIy40fB5hBNDA0ZDBbGyUihgpqmFcQ0K5Xu8NmS1QVEPo1g1DUa3Lu4nUQgQVBaGo5jen+Qtk+Dx2UFTHCNX/nqJan3k3KVJUy5gSnVroCwIU1TI2SImVoppCb+XPUlTnrwAU1fltYOeAomoT4XUwAYpqMKpiASmqxdBGR0xRjUbHBymq89cBiur8NrBzQFG1ifA6mABFNRhVsYAU1WJooyOmqEaj44MU1fnrAEV1fhvYOaCo2kR4HUyAohqMqlhAimoxtNERU1Sj0fFBiur8dYCiOr8N7BxQVG0ivA4mQFENRlUsIEW1GNroiCmq0ej4IEV1/jpAUZ3fBnYOKKo2EV4HE6CoBqMqFpCiWgxtdMQU1Wh0fJCiOn8doKjObwM7BxRVmwivgwlQVINRFQtIUS2GNjpiimo0Oj5IUZ2/DlBU57eBnQOKqk2E18EEKKrBqIoFpKgWQxsdMUU1Gh0fpKjOXwcoqvPbwM4BRdUmwutgAhTVYFTFAlJUi6GNjpiiGo2OD1JU568DFNX5bWDngKJqE+F1MAGKajCqYgEpqsXQRkdMUY1GxwcpqvPXAYrq/Dawc0BRtYnwOpgARTUYVbGAFNViaKMjpqhGo+ODFNX56wBFdX4b2DmgqNpEeB1MgKIajKpYQIpqMbTREVNUo9HxQYrq/HWAojq/DewcUFRtIrwOJkBRDUZVLCBFtRja6IgpqtHo+CBFdf46QFGd3wZ2DiiqNhFeBxOgqAajKhaQoloMbXTEFNVodHyQojp/HaCozm8DOwcUVZsIr4MJUFSDURULSFEthjY6YopqNDo+SFGdvw5QVOe3gZ0DiqpNhNfBBCiqwaiKBRwT1QsXLhRLmxG7CVBU3Vx4N4AARTUAUuEgFNXCgCOip6hGQOMjvxKgqM5fEyiq89vAzgFF1SbC62ACFNVgVMUCUlSLoY2OmKIajY4PUlTnrwMU1fltYOeAomoT4XUwAYpqMKpiASmqxdBGR0xRjUbHBymq89cBiur8NrBzQFG1ifA6mABFNRhVsYAU1WJooyOmqEaj44MU1fnrAEV1fhvYOaCo2kR4HUyAohqMqlhAimoxtNERU1Sj0fFBimq5OvDy5cugyCmqQZiqBqKoVsXdV2IU1fz2fPPmzYBXSw8cODC8ePFiNAGK6iii6gEoqtWRLzvB+/fv7zbqkFxSVEMohYX5+PHjcOPGjV0xhaDi79SpU6MPU1RHEVUP0KWoooKil8df6DSqOvmFJfj8+fPhxIkTm0b96NGj0RxSVEcRBQVAR3bo0KENexHVM2fODO/fv/fGQVH14pnlyy5FdRaSjSaKRnv58uV9DRqCOXZQVMcI+b+3OzIR0yNHjgxPnjzxP/y/bymqQZiqBqKoVsW9nMQ+ffo03L59ezh48OA+QYXIjo2QUBKKapw93759O1y6dGkfd9gCIvnly5fgiCmqwaiqBaSoVkO9nIQePnw4YDQkIyM5Y/ofsjgiJaGoComwMzqymzdv7uMO/qEdmZ0SRdUmMv81RXV+G1TLAQQTix8ionKGPw9+vakHRTWcmNaRwR5TOjIzRawX/P73vx/+7//+b59Nxbb8kWqTWJ3PTYrq1tbW8Ne//nXSNKkOzmWmgoW7q1evOhseRk4YQU09MIXd2dnZjfPw4cPDTz/9NDWKVYTXOjLMFCC0MYfLnhDW7e3tfTamqMYQTnumOVE9f/78gEaMnhgjpadPn6YR6Php+OYwPXT5TeHTgzBOPewp7G9/+9tN/Fitxj5LHsOuT9q1AIh6C192TEfms6eMTGGPc+fODUePHt1tIxTV+rWxKVHFNh/X1pNYgaiPu16KWD3W/KZYdY45XFt/0IClQcsZ+y0xmlrjAeHTFgBT6inqvsuewtw8ywwCwpqS5hrtl6PMTYkqCozGam+SlgoVO5XNAXIpccDPhhGjMJEzOqN79+5FuUy0KSwWtn7++WenayHWT7sUjjH5KNGRaezFrtpZhFW+Z9uIsWjcM82JqhQT00xNPGIWXSTeVs++ziZ25KjtYXUJtNb4IbyxI+NWbOHryGLrosZeRDLk/MMPP+zpXF12a4VxS/lsVlQFconRgcTdwhnTTYxA0WDshgZ/WoyPE/4+bQo7JtDaKjemoSF7X1tgLnl0LRiJDcApxm/qYy9xj53NKT/85qgH5jNcixALljk3L6rA4nPgx+7/K4M7b6xYpDO3NUnDge8tdgFPE8UpAq0JAxbMYhdp8pJLi006MtcC4BROdi409mLXsbNvVoD6YPtkU/Jq553XXwl0IapSHG3k0EtjlnKav2RkNjSUc+obORKnNoVFQwx9ZVLikjNGphg1mXnE55Q4Je65zlpHljL6g3vEtX/Y5qZdh07rtUU0bLdD2+GRh0BXoipINP8eGnPs3kCJe84zRoDaGzmxDcPXEcUKtM1Ie8cdPnGIeQuH1pGFCpqrjNrrqpp4uu6PuWNc6bo6u5QO2ZXGmu91KapiUG06hVFBK41ZyuLazoRGFitMPpdJrEBLXrWzVoYYYdDSyH0fnQ7y5xK0WE6+ztGVjutejqm7q7NrfeCR2/4x8XUtqgCi+fdQUWMbRQzo2GdcFR95T5lCa4t7Ka9MhpZPExQZ8YXGUyOc1gnEdmTIsxanSzhd91Ls7mKm+Ydr1AVXfnq4172oipFcUx5U2qVOe7SpYYp/WNuGNsfoxLUqDXv4FlvElqXPJToyLU6XcLrula6nmhuo54XeUvVoNaIqALXKnXsEIOlNPftG1rEVXJvCpgj01HJp4bWFnzm2YPk6slj/suaLdQmndq/mjEpbj+DLA1oN3n9/daIqCLRpGKZ2aAhzHD4fMCr71EOmdq49rOZexqnx5g6v5bOW6GsuCYhc7o5ME07X/Tmn4K72gXqE+zz8BFYrqsDia0w1F0+00QEqcexuBW0EuITptVYltRE1ZhEh/95Fi3fsPkQdXExhixU0rYMw4x77PIc7xsVIs0fK9jFXOr3dW7WoijG1KZosnqChlDhQaTEScjWy2OmW5qtsaZSh7ZlNWSAasx86IdghRdC0jsxlX9e9WiPzMRb295o9cuxAsNPq4ZqialhRaxQleubSP8lnNtqao24DZ/JHbZfCtWvXimxWR3qYvUw9IDoQGJP51M9Lcsdo5dd+KauUPbR8LP0+RdWykG/6lrPiY/HBbHgp03KX/wtx9zCSgD1cHVDpWYRVLZyXmGnYdjRtGvI5xe7OTBW+qbnMSu9OKFysrNFTVBWcvgYTOzU3k0L8qIgiDuZ3oZ+1nQwlRtaheSoVTrPHHKKkCX2IiEqYltwxLptqbqal7KJx5bnWPYrqCGnNn5SjUUAUIRZTjxJbf6bmYa7w2qJezlmEr2yaS0LEMuTcqjvGxQUuMwipXW4s9IX+Ktnr16+Hu3fvDleuXNkTz7Fjx4br168Pjx8/Hj5//uxKft89xCV5QXxTj5RnJS2KqpAYOWuNqeZICVMv7Sf5au5lHEFV5WvX9rOSCz1a5yqNMOTcgzvGZVyM3O16idkS7vsOCKDrP0doLB88eOCLbvc7iuooomUFcFUeqQCx+xlDS+gSEaRdckU8NG9zhdM6GYyccm3BwmhL26Ehth879+iOcdncfGsRI1jf8ezZs82Icoyf+T1E2Ddqpaj6qC/4O62hlRgpadPdnMKxYNRBWTMbs9kAUzocTbDN+Mc+r3XxZuzlGUznbXa3bt3a/VfdpmC+e/dud+oPN4AZ3iesFNWgJrPcQD7Bi920L6WtKdySZutnbeFuqmtEmxWYDXvs89Q0W2cfmn9T9MAQAvnhw4fRxzH1N5lr/lIzfi2MLzFJI+ZZiZc+VSGRcEYjxMKVGETOcNbDFzfl8K0sl3YxTMnnksO6tpjJLgufn0/rJMWeIeeU0fGSmebKmznq9I04XenZLgPYyz4oqjaRhq+1/XtoiKGjliUshjVsgj1Z1+wB/yZGtOahzQpCRFTC0B1jEnV/hggKL5xDRqh2TNgNIHG4RpMUVZtYB9cx2520leUc27Y6QJpUBG0/JbZgvXr1Sv1PCtJwx84l/OhJBV7ww/CbCk98jjkgxBIHzrYwU1RjqDbyjObfw4gGI1Ic2oZ2VJYcLxg0gqpKNl2vIG9tbQ3Hjx/f00jNBjv2me6YaaYzp/6uqXtobHAbiG3gEjAPiqpJo8PP8N9p/z76+++/332jSiqHnLGXEaMrHvkJuOxx+PDh4ejRo5tGKnbwnWvuTc5PYb4YTabmKv/UHOFFAYnL3rtqiqqEiTm7XAuh+eRCVSiphHAYkdr/5wiLWKax17KXMQFjtkdte0BUMWo17eH6THdMvAmwPcpkGh/TMJg7AWzxo6imkG3wWfMnBkVUQ1alGyxqE1kWX/bJkyed/0rbFAG6Y9JMaotdSmwU1RR6nT4Ln+p3330XvCugUwyLKRbEEwtO+DOFFJ/pjsljpjlE1R7FhpRE7B/zrMTP6b+Q4Hm1BKQhnT17diOqdMfkrw7CGeeUI9SnGiOMkseYZ6VMaaWTWHgmgYYJSEOCqNIdU86Q5uo/Rq6xB1f/Y8nxORKoREBEFYtVMT/FWCmbzSfDfarNm5AFIIEwAiKqOPMoR8D2q9ob90NSNt+owojVPsw0YqbwUhdinpW8sBYJCZ5XS0AaEkW1fBWAWAlvvvtfnjdTIIFZCEgjp6iWx2/vV4WwhoxYzW1UsJM2kuRItbwNmQIJjBKgqI4iyhrA/rUp8J/ye6pY8NLeyKKoZjUVIyOBOAIU1ThuKU+5hNW0g/Z5bGRLUU2xCp8lgUwEzAacKUpGE0AArgDTx2rawfUZLgBthCrJUVSFBM8kMCMBswHPmI3VJg1x9f03VYxqx8RU4FFUhQTPJDAjAYrqjPA7TJpbqjo0Kos0jQBFdRovhvYToKj6+fDbFRCgqK7AyBWLSFGtCJtJLZMARXWZdmk1VxTVVi3HfGcjQFHNhpIRDcNAUWU1WD0Biurqq0BWABTVrDgZWYsEKKotWm25eaaoLtc2zFklAhTVSqBXkgxFdSWGZjF1AhRVnQ2/mU6AojqdGZ/ojABFtTODzlwciurMBmDy8xOgqM5vg55yQFHtyZosSxQBimoUNj6kEKCoKmB4ez0EKKrrsXWNklJUa1BmGosmQFFdtHmayxxFtTmTMcO5CVBUcxNdd3wU1XXbn6XHa4UHDmz+CIQEUglQVFMJ8vnmCVBUmzfhogpAUV2UOZiZOQhQVOeg3m+aFNV+bcuSBRKgqAaCYrAgAhTVIEwM1DMBimrP1q1fNopqfeZMcWEEKKoLM0jj2aGoNm5AZj+dAEU1nSFj+EqAovqVBT+tlABFdaWGL1RsimohsIy2HQIU1XZs1UJOKaotWIl5LEqAoloU7+oip6iuzuQssE2AomoT4XUKAYpqCj0+2wUBimoXZlxMISiqizEFMzIXAVNUP336NFc2mG4nBCiqnRiSxYgnYIrq+/fv4yPikySAH+ghBRJYOwGK6tprQN7yU1Tz8mRsDRKgqDZotAVnmaK6YOMwa3UIUFTrcF5LKhTVtVia5VQJUFRVNPwiggBFNQIaH+mLAEW1L3vOXRqK6twWYPqzE6Cozm6C4fPnz8Pr16+HBw8ebP6ePXs2vHv3blLmPnz4sOf5SQ8PQ9KzkhZFVUjwvFoCFNX5TP/ixYvhypUrm/8RZtrC/AyxhfCOHRBmeQ7xTj1SnpW0KKpCgufVEpCGhDP3qdapBhDIEDE1bYPPEGHfQVH10eF3JFCJgNlwKarloWOKfu7cuc2IUvjj3t27dzdT8OvXr+8Lg7BwC2gHRVUjw/skUJGANGqcKaplwWOEagvqrVu3BgitdkBETRv5hJWiqlHkfRKoSMBssBTVsuAxEjV5+0adZk5cYuzysVJUTWr8TAIzETAbOUW1nBEwGjVZP378eFJiEFHzeQi0fVBUbSK8JoEZCJgNlaJazgAQUWENF0DMYbsC7DgoqjaRzq/RYP/xj38M/Hm5ZRlaGjrOFNVytjFX+6eOUs1cmfaCiJoHRdWk0fFniOjt27eHgwcP7vbU33333XD//v2OS9xW0cxGSlEtZzuT89RN/WauzF0B2L9qHqaoHjt2bLOTwHypwPdZ8hizx1XywX2qQqLQ+eHDh8ORI0c20x4YbWtra9je3h5OnDgxuu+uULYYrUFAGhLOFFUDTMaPtj80JWqIotgMOwfMwxRVCRNzpqiaVBfyGZuUT506tTG+bViIqoxcL1++zMY8g93ERrAFZg8nT54cvvnmm+Hp06cz5KbvJG2xSymtKaq2+Nnp2O0u9NqOd0p+OVKdQisgLEY6EMkQ450+fXoTDgJ7586d4cuXLwGpMEgKAZeNdnZ2NraA7S5cuDC8efMmJRk+axCwxc74avLHUFHl9H8y2mU9YPtNQ0QVYezGDFfBkydPllW4TnLjs9GNGzc2MwfTdrj/8ePHTgjMVwx7O1VKTkxR9U3/Y0abYvuYZ6VMHKkKiYQzFp0OHTq0Z6Qjxgk5u9wEHCklGMTxKDoq27cN25icXSNYhIFtubDogDrxltkWfG9QjUUbulAVI4ySx5hnJd8UVSERcX7+/PnuYpMYIuaMRv3f//53z+4AMx6MlLgFK8I4/3vk5cuXw5kzZ/Z1eBBYzXcKXysWEU074DPuweY84ghAqIRp6JtUrpQkDpzhVjAP080QI4wSd8yzkg+KqpCYcH779u1w6dKlTQURQ0w5o4HajRojJVe8HClNMM7/gmLKfvXq1X02muK71mYgsBHqAI9pBMzN//B3xhzc/B9DbcHPYMR48+bNfQ11ipiGCKQ2AuZIabxyYKHv3r17TncMRHaqf1SzOcQZe485ixi3iYSwt1VNfQHAft72pyIdjlSFdgNnbdQyRVAhyFMaoSYO3ILlrjAY+WNLlG0TTP/hBkg5tNkJ3AjYi8wjjIC5yAQ7hboBIKj2r1vhnn1QVG0iC7xGQ3X51+yG67tOmS5iZAW/qh2/jJS4BWvY3foE37TNqITgacKNxcaxH1BeYPUukqWx2YAtjvzpvyJmWF6k2KPoaqh2w/Vdo6HlWthAfrQFl7VuwZprap7bxbC82h+XI6mj6Mx8nb1r1Il2BLEN+ZFqjHa1gyNVjcyM97WRoU887e9KjJAEibY1CIK7ps3qmjsGswIs+NU4UFeuXbu2b4Q8ZTGsRj5Lp+FqM3iRxXdAWM2tUXYb0q7H3AUUVR/1yt/5Rh+age37MiWf4jeNKSbyav5Ai5mP3jer517EA8tHjx7FmGHzjG/bVs+zCF+bQecWckAEx8RV3oxy+VDtNCiqNpGZrjU/mSlWY5/nWDxa02b1EmU17Z5jc782izBfMJipimdPVuvcYn87AYIJQcTUXv4wKp36a1Z4qcB8fmrBU56VtFa9TzWX33TuBYqeN6tj1K+NyqfuppBK77I7XDZjCyzyvO+M0Rumvpi12B1xD7MIbRcEyovdKij/2o9ViqrmC7Mbge8ajTB22ohRUY4GbFfeJfgZ7TylXLt+NhE2iR35QaBdOykQZ8weVl/ZfCPrFsVHOjdXm8jNzse1he9WJaq+UYSrsrjupSxCmFMmVMQShyYctfy9Ocqk+Shjp5bIk9bh5NjD6iszZhGu33Zo6UUOrXMrzc7HdcnfrUZUNX+XSzi1e7E9MkYtcNzb8aZuSPdVLNcUF+ljhL3UxROM3sHY5oS30GJHd2ZHZsZbm4MmTCl7mH32z/Gd1iHUZpejLDXj6F5UtVGP2cDGPsf2yDJlcvnXai1sYTEGjeOQhqUAABdJSURBVMAuY2yZSlRO3wwitiPz+f7go53D94f6oL3mHOsfLmEPrXNLmaWVyOdS4+xWVLWKYYuL7zqlR9ZGJnO8eeMTrbkXT8wVeNMWsaIvHZkZl3yu1ZGNNXZN8FHfUG/mOnz1JLZzm6ssc6bbnaj6KoY0rrFzynRTGxmH/JBK6YqAjgbCYpdfyls6fTP+Eu6JJXVkZlm1z5prYo6Ot4UZjcZxafe7ElWtUdki4ruOHbn5RsZLmtqhAmq+shqLJ+DkWoFPWUjTyjP3yC+ksWMQMOcP55To3ELK3XOYLkRVa1Q+8bS/i92m4xsZL3kRApUanRBGqTaLUvnWVuBjp+XayBvlWVpHNiYivs6mxP8uq53eWPl7+r5pUdX2Atoi4btO2aajTZlS4qxdubTFk5SRo12G3NPcljsym419XWPkqHVu9Jva1oi7blJUZTHCtaruE1DzO/EjooFOPbSKnxLn1DzkDo/FE9evcmEKHfuSg7YgA05o2DGHtjWuhusiJr+xz2jljF3AQz58nVvJ7X2xDFp9rjlRzeE3jZ0aalMmiHWsL3ZpFSfHaryv04tl71sAhE+yx8M3Ip9S37TOrQWfc4t2bUZU0cu63kwxR59jn1N8hdqUKWXksNQKg8YMoXLNBPBTd+hctEPr9GLZr6Ej01jKfTCIeSlC69xyunYkjzx/JbB4UdV62TEBNb9PmRpqUyb08kt9M+mredM+TWnM2mJhrH9ZhN21kBa7qJhGY/6npzDWOrfYRcH5S99ODhYvqj/88MNw/vz5fSvUpmhqn1N8d5qYo5cvsRq75CqDqbdrloDO6ueff44aRfnKq7kg0JHhu7UfmmBiNvDvf//b+R8i5tj7ulY7LV5U5ZfVjx8/7mzYLkFNmd5oUyaks/Ze3tWY7f83BE5T/H1mw2NHZtLwf9bqqW0P+k39HEt824yoiniePXt2OHz4sDpyTRE+l2ggXfbyX6ueNGaxx/fffz9sbW3t2iPWv4w4sYAlcZpnbvP5yt71yeyIMJj43e9+t8sxZWDhSof3wgk0J6pocKgwOzs7exZSUoRPm97CfQCh5bGfABozbAB7oJP76aef9gcKuLOmBcAAHNFB/vWvfw3b29u79sCsDnu4ecxDoElRlZEMGjMadqzwaQsxiD926888ZpwnVSxCiS2wiDLl8C0AxtpzSvq9hYWIii1w5jEfgcXTF5+qWWHMz1gJnnr49v/Fbv2ZmocewseIqvYWHKeraTWCoprGL+fTqxNV36ulGD3xCCcwRVTFFwvxNDtFfE7xg4fntu+QFNXl2Hc1otrjq6VzV6MpooofhrbFFFuyproN5i7zUtOnqC7HMqsQVW1lOXbrz3LMN29OpogqRqrY3gNhTdk/PG+J66eOmRX2RePPt0eXolrfNlqKqxBVe5QUu/VHg7jW+1NEFYzwwyxcAJxWW8w1BXzWDoqqRqb+/VWIKhamMErCX++vltasQlNFtWbeekmLotqeJVchqjAL9lVCXHnkI0BRzcdSi4miqpFZ7v3ViOpyTdBuziiq5W1HUS3POHcKFNXcRFcUH0W1vLEpquUZ506Bopqb6Irio6iWNzZFtTzj3ClQVHMTXVF8FNXyxqaolmecOwWKam6iK4qPolre2BTV8oxzp0BRzU10RfFRVMsbm6JannHuFCiquYmuKD6KanljU1TLM86dAkU1N9EVxUdRLW9simp5xrlToKjmJrqi+Ciq5Y1NUS3POHcKFNXcRFcUH0W1vLEpquUZ506Bopqb6Irio6iWNzZFtTzj3ClQVHMTXVF8FNXyxqaolmecOwWKam6iK4qPolre2BTV8oxzp0BRzU10RfFRVMsbm6JannHuFCiquYmuKD6KanljU1TLM86dAkU1N9EVxUdRLW9simp5xrlToKjmJrqi+Ciq5Y1NUS3POHcKFNXcRFcUH0W1vLEpquUZ506Bopqb6Irio6iWNzZFtTzj3ClQVHMTXVF8FNXyxqaolmecOwWKam6iK4qPolre2BTV8oxzp0BRzU10RfFRVMsbm6JannHuFCiquYmuKD6KanljU1TLM86dAkU1N9EVxUdRLW9simp5xrlToKjmJrqi+Ciq5Y1NUS3POHcKFNXcRFcUH0W1vLEpquUZ506Bopqb6Irio6iWNzZFtTzj3ClQVHMTXVF8FNXyxqaolmecOwWKam6iK4qPolre2BTV8oxzp0BRzU10RfFRVMsbm6JannHuFCiquYmuKD6KanljU1TLM86dAkU1N9EVxUdRLW9simp5xrlToKjmJrqi+Ciq5Y1NUS3POHcKFNXcRFcUH0W1vLEpquUZ506Bopqb6Irio6iWNzZFtTzj3ClQVHMTXVF8FNXyxqaolmecOwWKam6iK4qPolre2BTV8oxzp0BRzU10RfFRVMsbm6JannHuFCiquYmuKD6KanljU1TLM86dwmpE9cmTJ8ObN29y81t1fBTV8uanqJZnnDuFVYjqx48fh4MHDw4HDhwYbty4MeCaRzqBqaL65cuX9ERXFgNFtT2Dr0JUr169uiuoEFX8HTp0aLh371571lpYjqeK6u3bt4dTp04NL168WFhJlpsdiupybaPlbBWiev/+/V0hFVGV84kTJ4bnz59rbHh/hMAUUX379u1mtgD+ly9fHt6/fz+SAr8GN3RC+MNn7QBLqdc485iPwOLpmz21WWnk84ULF4Loffr0abh58+aeiidxXLp0yVthgxJYYaAponrnzp197OGSwX26BdIrD0U1nWGuGFYjqgIMvT1EVATVPGN6CvHlEUZgiqgiRswKMDswmePzkSNHBiwk8ognQFGNZ5f7ydWJqgD0NfCHDx9KMJ49BKaKqkSluWPOnDkzvHz5UoLxPIEARXUCrMJBmxbV06dPD4cPHx6wEBWzoo9pJxassHBlj564oDJe82JFFTHDXtiJYXPHdaw9x3PcbwiK6nJs26SoHj9+fHcV2WyQKf45NvDpFfLp06fDxYsXdxef0AH9+OOPUa4T7B2GX9y0JT7LDg36W8dtA0Z/+9vfBgwyhOP4UwxRikBTorq1tTWcP39+U3GkApnnFP+c1sBTBLuU4eaK12b0m9/8ZmMPsI91nUCkzZGv2BT38B0PNwGbGzo4DDp4zEegGVHd2dkZIKrS2MbO8M/F7odERYVA2GmkCPZ8Js6TsrZ74ty5c/s4xbpOxB0jL2qY/DGa5RtxX21pd27CSkb4X0PyU20CixfVv/zlL8P29va+hiuVaOwcux8SDRzbfdjAh0FbWALbX375RfVLx/pG4Y6xX9gQO2Nb3Jp3aGidG/jwbcHa8ulOb/GiKqMX12KSNLSxM4QxdruUr4H3Xokx0ndtgXK9NKFxSnGdYCcAZhy2fVEXIPRrO7TOjaP4ZdWExYuq4EKj1Tbv241Ou07x+fkaeG+vvGIlGaNQm2OImGmcUlwn2MPqcse4xF3qS09n3/Y/+puXZ+lmRFXQ+Tbv2yKgXcf6/JCHR48eddvAMSvAiN7l8sCofMq0WxPC2L2oSFvLG17mQEfQ26HV9ZTRf2+Mllie5kRVIGq9tyakrvuxr6eONXDfO9qS/6WdNRFMmVr6OMW6TrRRdIqLZ2m28HGL9VMvrYw956dZURWjaH4ml4hq92IXP7QGjnRi45Ry1TqXmK7bedc4yUo1RshTD/h7MeOwbZri4pmahxLhsSXN5eqIHeGXyCPj9BNoXlRRPPTsqf7WEH+hhrLFBg4fNUaLtiiVnFpqC18pe1G1ThWCiw6jlaPFOtQK29r57EJUBRqm3a4FFls4fNcpix++Bo5Gs4TDt5sC7CC2pQ+NE1wNMa4TX6e69OkyeLvqbE/ujNL1aWnxdyWqAlfr9X1ian8Hf2vMZnNfA68lWsLBPmt+6JSFOzuN0Gsfp1jXSUsLO+jctH3QqCc9LryF1o3Ww3UpqmIUzT9lC6jvOnZBZUkNXMsLXB6xr5UK49Qz8oYRqm2DFHcMOg/XK68p27pSy2k+ry0KpsySzPj5eV4CXYsq0GJEpG3FsRuydp2yoKKNDtHAS7sEpOyucsWOBktVV/sddslzrND43BxY9ImZhaSWXVsUTOlAUvPE5/MT6F5UBZm2Ai2NN+Qcu6DiauDwmZX0X2qj9Fi/pXAseXZxErvE7kXVFuQQb+wsZCoD5EH7DxZL69ymlo3h9xNYjahK0XP4W2P3bpoNHP60EgdGQ66tRrEdQok8jsUJTq53/1MWb8Z+gASCnvvwdRJL7txyc1hbfKsTVTGw9maUjIxCzhh9QACmHmjguRuxT4jwGm3u9KaWOSa8Nl1O2Yuq+TPR6cC/m+vQ3BktdW65WKwtntWKKgwNodFWYENEFWFK7usMqYy+Mix9O1FI+RBGE8LYXQsuZogrR8czx4g4lCPD1SGwalEVxNooL1RYEW6OlWVtNNTj2zey6IZOzLZLbOdh2h0LiimHb4tY7IwmJT98dj4CFFWDvTbdtBux77qGoGmjoZRpsYFh0R+1BceUGUPqnlDtZYYadWHRxlpp5iiqDsNr002fmNrfxY6eHNnZ3MJoyPVqKdKO/b3YTeSNfcCCI7Zb2dxrzhh82+VQh3iskwBFVbG7y+9mN+Cx65TVajtb2mgo9pe27Phbvda4lBwlai9TpIyWW+XPfO8nQFHdz2TPHfjdtNHhmKjK9ynTcm00FLspfk/hOrnw+TNz7kX1+XX5amknlSlDMSiqgRA1P6YIZ8h5ymq15jtMebsrsKjNBvO98pq6rUx7mWKKTZsFy4xPIkBRnYRr2P13ydhrGCKiWhjfqMY3Gso56ppY7KaCa7siYvaIai+LpMw+moLJzE4mQFGdjOzX/a0Y+WDUqAnn2H343+xXFLUFspL+wYjiN/EIfOKajULeZoLbB52fy4623ZoAwkxWI0BRTUCdw98KYf773//u/K+hNVeyEzAs+lFzL6otkC5x9C1Qrn1RcNGGXlDmKKoZjJHib93a2hqOHj26Z0SUc9dAhuJ1EYW2B9n8hShtpsBFwS6qQLVCUFQzotZW6u0RknmNhQ7z2udvzZjV1UalCefFixf32AE2kUXB1cJiwaMIUFSjsPkf0vZOmuKJz/DtyT2OhvxMc37rWgzc2dnZ2AI24aJgTuLriouiWsjevr2TaLSnT5/ebcTm9LNQVhitQsDctiaiGvuzjkoSvL1CAhTVwkZ3vX2zvb09wJeK0RDEl8e8BLBtCrbAViweJJBKgKKaSjDwefG3YhEKvwuAxS0eJEAC/RGgqFa26atXryqnyORIgARqEqCo1qTNtEiABLonQFHt3sQsIAmQQE0CFNWatJkWCZBA9wQoqt2bmAUkARKoSYCiWpM20yIBEuieAEW1exOzgCRAAjUJUFRr0mZaJEAC3ROgqHZvYhaQBEigJgGKak3aTIsESKB7AhTV7k3MApIACdQkQFGtSZtpkQAJdE+Aotq9iVlAEiCBmgQoqjVpMy0SIIHuCVBUuzcxC0gCJFCTAEW1Jm2mRQIk0D0Bimr3JmYBSYAEahKgqNakzbRIgAS6J0BR7d7ELCAJkEBNAhTVmrSZFgmQQPcEKKrdm5gFJAESqEmAolqTNtMiARLongBFtXsTs4AkQAI1CVBUa9JmWiRAAt0ToKh2b2IWkARIoCYBimpN2kyLBEigewIU1e5NzAKSAAnUJEBRrUmbaZEACXRPgKLavYlZQBIggZoEKKo1aTMtEiCB7glQVLs3MQtIAiRQkwBFtSZtpkUCJNA9AYpq9yZmAUmABGoSoKjWpM20SIAEuidAUe3exCwgCZBATQIU1Zq0mRYJkED3BCiq3ZuYBSQBEqhJgKJakzbTIgES6J4ARbV7E7OAJEACNQlQVGvSZlokQALdE6Codm9iFpAESKAmAYpqTdpMiwRIoHsCFNXuTcwCkgAJ1CRAUa1Jm2mRAAl0T4Ci2r2JWUASIIGaBCiqNWkzLRIgge4JUFS7NzELSAIkUJMARbUmbaZFAiTQPQGKavcmZgFJgARqEqCo1qTNtEiABLonQFHt3sQsIAmQQE0CFNWatJkWCZBA9wQoqt2bOG8Bnz17Njx48GDzh+uUI3d8KXmJedZkgc+vX7+OiYbPdESAotqRMWsU5cqVK8OBAwc2f7hOOXLHl5KXmGdNFvgMYeWxbgIU1XXbf3Lpc4tg7vgmFyjxAYpqIsAOH6eodmjUkkXKLYKtT/8pqiVrW5txU1TbtNtsuc4tqrMVJFPCFNVMIDuKhqLakTFrFIWiupcyRXUvD14NA0W10Vpgrzp/+PBhtyQvXrzYrMzj8+fPn7OW0CeqyIM5nUf6Y4cZHmXCtX3YZTW/x2q7+f27d+/Mr4M+2/l+/Phx8Co+RTUI8aoCUVQbNbfdmCEu586d26zKy/cQwZyHS1Qh3Hfv3t2XtuQBIqUdrvjssBKPnPE9BPvYsWPONHE/RFwRh4uZpIMzBNvXMZlhJbydf16viwBFtVF7241ZE4fc+yZtEUS6WtpmHm/duuUkbceHa/sw48Fnn4CbYWX0bseHa+THDOv7jPJpwmo/BxHmsW4CFNVG7W83ZrmGKMl02DdCjC22LYKSLs4QKqStCZZLcOz4QkRV0sSIFHFCZF2jVk3IXfnD84gH8dl5QnqasEpe5OwqYyxrPtcmAYpqm3ZzjrI0EclZRJfgQFDs6TZGiS6hs0d8dnyhomqXFfG60rPLjpG7CKCc7bjwTGg4iUPOFFWb+PquKaqN2lwasXn2TXdzFdMWQaTvWlxCei5hssPa8YWIKsTTdUDQTB74bB8h6ckzGOnb8dmM7e8pqkJvvef9tW69LJoqud2YMT2tcdii5BIuMx/26NEeFdrxhYiqHYekB8G2uch3OEMQ7e9tkTfD47Md3hbNse/t+HjdPwGKaqM2thuzS4xKFC1EBM10x8KPfY+47LLawibpuUbGplsCq/12XPbIU+KS81j+7Pi0vEl8PPdPgKLaqI3txnz9+vUqJRkTGTsTY+HHvkd8dlk14XKJKu7JgefsuOQ77TyWPzs+LW9a/LzfHwGKaqM2nasxj4mMjXMs/Nj3iC+0rBRVmz6v5yBAUZ2DeoY0Q4UmQ1J7orBFUFs0kofs8Lg2j7HvETa0rGOi6vqe03/TGvycgwBFNQfFGeIIFZrcWbNFEPmwt0mZadoLVdgLah52fLboImxoWV2iiXty5Fiosvf+huZN8sBz/wQoqo3aeK7GbIsg8qH5EV0iZ/8egB1fSVGFqe23v1zpSZXgliohwfMUAhTVKbQWFHZJooq82FuTMCq0R6kuV0FtUXVtu3Jt0XJ1CPYoG9VhLjssqCoyKxYBiqoFpJXLuRqzLYJmPrADAaNWiI95Xz7bo1SwtuNzjRzleTlPGRmb03+xLfIpcckZgs/XVIUQzykEKKop9GZ8VsRAzprQ5M6iLYIugZI8mWctf3Z8NUQVPuDQfKMM2nv/YGuWEZ+1cua2A+NbLgGK6nJt483ZXI3ZFkGICDbY21N9yR/uu0aoUjg7vhqiKmkjX7aPVfIt5zGRlHByHgsvafPcLwGKaqO2ReM1/1zT3BJFg09SSxfiisUd+T4kT3Z8tm8WZZD45KzFCz+uhJHz2JYpxI8wZj5QBi0Nm6mkI+fQ5+x4eN0PAYpqP7ZkSUiABBZAgKK6ACMwCyRAAv0QoKj2Y0tnSWRamnrmtNaJlzdJYB8Biuo+JH3dkAWU1DNEmQcJkMA4AYrqOKOmQ6SKqTxPUW26GjDzFQlQVCvCniOp1Gm/PM/p/xzWY5otEqCotmg15pkESGCxBCiqizUNM0YCJNAiAYpqi1ZjnkmABBZLgKK6WNMwYyRAAi0SoKi2aDXmmQRIYLEEKKqLNQ0zRgIk0CIBimqLVmOeSYAEFkuAorpY0zBjJEACLRKgqLZoNeaZBEhgsQQoqos1DTNGAiTQIgGKaotWY55JgAQWS4CiuljTMGMkQAItEqCotmg15pkESGCxBP4fb+MdrmwTFpwAAAAASUVORK5CYII="
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CDXMLFile to Optimized Structure Example\n",
    "\n",
    "The `molli` package does not have native geometry optimization; however, the interface with `openbabel` allows for the use of molecular forcefields to return updated coordinates for the `ml_mol`. This will be shown with an axial chiral structure R-BINOL.\n",
    "\n",
    "![image.png](attachment:image.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/blakeo2/new_molli/molli_dev/molli/molli/ftypes/cdxml.py:157: CDXMLSyntaxWarning: CDXML file /home/blakeo2/new_molli/molli_dev/molli/molli/files/parser_demo.cdxml contains redundant label 'naphthalene' Only the first occurrence will be kept.\n",
      "  warn(\n"
     ]
    },
    {
     "data": {
      "application/3dmoljs_load.v0": "<div id=\"3dmolviewer_17295394453724828\"  style=\"position: relative; width: 100%; height: 500px;\">\n        <p id=\"3dmolwarning_17295394453724828\" style=\"background-color:#ffcccc;color:black\">You appear to be running in JupyterLab (or JavaScript failed to load for some other reason).  You need to install the 3dmol extension: <br>\n        <tt>jupyter labextension install jupyterlab_3dmol</tt></p>\n        </div>\n<script>\n\nvar loadScriptAsync = function(uri){\n  return new Promise((resolve, reject) => {\n    //this is to ignore the existence of requirejs amd\n    var savedexports, savedmodule;\n    if (typeof exports !== 'undefined') savedexports = exports;\n    else exports = {}\n    if (typeof module !== 'undefined') savedmodule = module;\n    else module = {}\n\n    var tag = document.createElement('script');\n    tag.src = uri;\n    tag.async = true;\n    tag.onload = () => {\n        exports = savedexports;\n        module = savedmodule;\n        resolve();\n    };\n  var firstScriptTag = document.getElementsByTagName('script')[0];\n  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n});\n};\n\nif(typeof $3Dmolpromise === 'undefined') {\n$3Dmolpromise = null;\n  $3Dmolpromise = loadScriptAsync('https://cdnjs.cloudflare.com/ajax/libs/3Dmol/2.0.4/3Dmol-min.js');\n}\n\nvar viewer_17295394453724828 = null;\nvar warn = document.getElementById(\"3dmolwarning_17295394453724828\");\nif(warn) {\n    warn.parentNode.removeChild(warn);\n}\n$3Dmolpromise.then(function() {\nviewer_17295394453724828 = $3Dmol.createViewer(document.getElementById(\"3dmolviewer_17295394453724828\"),{backgroundColor:\"white\"});\nviewer_17295394453724828.zoomTo();\n\tviewer_17295394453724828.addModel(\"@<TRIPOS>MOLECULE\\nr_binol\\n36 39 0 0 0\\nSMALL\\nNO_CHARGES\\n\\n@<TRIPOS>ATOM\\n1 None -2.9524 3.0000 0.0000 C\\n2 None -2.9524 1.5000 0.0000 C\\n3 None -1.6538 0.7500 0.0000 C\\n4 None -0.3538 1.5000 0.0000 C\\n5 None -0.3538 3.0000 0.0000 C\\n6 None -1.6538 3.7500 0.0000 C\\n7 None 0.9448 0.7500 1.0000 C\\n8 None 2.2434 1.5000 2.0000 C\\n9 None 2.2434 3.0000 2.0000 C\\n10 None 0.9448 3.7500 1.0000 C\\n11 None 0.9448 -0.7500 1.0000 C\\n12 None -0.3538 -1.5000 1.0000 C\\n13 None -0.3538 -3.0000 1.0000 C\\n14 None 0.9448 -3.7500 1.0000 C\\n15 None 2.2434 -3.0000 1.0000 C\\n16 None 2.2434 -1.5000 1.0000 C\\n17 None -1.6538 -0.7500 2.0000 C\\n18 None -2.9524 -1.5000 3.0000 C\\n19 None -2.9524 -3.0000 3.0000 C\\n20 None -1.6538 -3.7500 2.0000 C\\n21 None 3.5434 0.7500 2.0000 O\\n22 None 3.5434 -0.7500 1.0000 O\\n23 None -3.8790 3.5351 0.0000 H\\n24 None -3.8790 0.9649 0.0000 H\\n25 None -1.6548 -0.3200 0.0000 H\\n26 None -1.6548 4.8200 0.0000 H\\n27 None 3.0143 3.4452 2.5936 H\\n28 None 0.9448 4.8200 1.0000 H\\n29 None 0.9448 -4.8200 1.0000 H\\n30 None 3.1700 -3.5351 1.0000 H\\n31 None -1.6548 0.3200 2.0000 H\\n32 None -3.7233 -1.0548 3.5936 H\\n33 None -3.7233 -3.4452 3.5936 H\\n34 None -1.6548 -4.8200 2.0000 H\\n35 None 4.3663 0.2753 2.0000 H\\n36 None 4.3663 -0.2753 1.0000 H\\n@<TRIPOS>BOND\\n1 1 2 2\\n2 2 3 1\\n3 3 4 2\\n4 4 5 1\\n5 5 6 2\\n6 6 1 1\\n7 4 7 1\\n8 7 8 2\\n9 8 9 1\\n10 9 10 2\\n11 10 5 1\\n12 7 11 1\\n13 11 12 2\\n14 12 13 1\\n15 13 14 2\\n16 14 15 1\\n17 15 16 2\\n18 16 11 1\\n19 12 17 1\\n20 17 18 2\\n21 18 19 1\\n22 19 20 2\\n23 20 13 1\\n24 8 21 1\\n25 16 22 1\\n26 1 23 1\\n27 2 24 1\\n28 3 25 1\\n29 6 26 1\\n30 9 27 1\\n31 10 28 1\\n32 14 29 1\\n33 15 30 1\\n34 17 31 1\\n35 18 32 1\\n36 19 33 1\\n37 20 34 1\\n38 21 35 1\\n39 22 36 1\\n\\n\",\"mol2\");\n\tviewer_17295394453724828.setStyle({\"stick\": {\"radius\": 0.1}, \"sphere\": {\"scale\": 0.15}});\n\tviewer_17295394453724828.setHoverable({},true,\"\\n        function(atom,viewer,event,container) {\\n            if(!atom.label) {\\n                atom.label = viewer.addLabel(atom.elem + '(' + atom.index + ')', {position: atom, backgroundColor: 'silver', fontColor:'black'});\\n            }\\n        }\\n        \",\"\\n        function(atom,viewer) { \\n            if(atom.label) {\\n                viewer.removeLabel(atom.label);\\n                delete atom.label;\\n            }\\n        }\\n        \");\n\tviewer_17295394453724828.zoomTo();\n\tviewer_17295394453724828.setBackgroundColor(\"white\");\nviewer_17295394453724828.render();\n});\n</script>",
      "text/html": [
       "<div id=\"3dmolviewer_17295394453724828\"  style=\"position: relative; width: 100%; height: 500px;\">\n",
       "        <p id=\"3dmolwarning_17295394453724828\" style=\"background-color:#ffcccc;color:black\">You appear to be running in JupyterLab (or JavaScript failed to load for some other reason).  You need to install the 3dmol extension: <br>\n",
       "        <tt>jupyter labextension install jupyterlab_3dmol</tt></p>\n",
       "        </div>\n",
       "<script>\n",
       "\n",
       "var loadScriptAsync = function(uri){\n",
       "  return new Promise((resolve, reject) => {\n",
       "    //this is to ignore the existence of requirejs amd\n",
       "    var savedexports, savedmodule;\n",
       "    if (typeof exports !== 'undefined') savedexports = exports;\n",
       "    else exports = {}\n",
       "    if (typeof module !== 'undefined') savedmodule = module;\n",
       "    else module = {}\n",
       "\n",
       "    var tag = document.createElement('script');\n",
       "    tag.src = uri;\n",
       "    tag.async = true;\n",
       "    tag.onload = () => {\n",
       "        exports = savedexports;\n",
       "        module = savedmodule;\n",
       "        resolve();\n",
       "    };\n",
       "  var firstScriptTag = document.getElementsByTagName('script')[0];\n",
       "  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n",
       "});\n",
       "};\n",
       "\n",
       "if(typeof $3Dmolpromise === 'undefined') {\n",
       "$3Dmolpromise = null;\n",
       "  $3Dmolpromise = loadScriptAsync('https://cdnjs.cloudflare.com/ajax/libs/3Dmol/2.0.4/3Dmol-min.js');\n",
       "}\n",
       "\n",
       "var viewer_17295394453724828 = null;\n",
       "var warn = document.getElementById(\"3dmolwarning_17295394453724828\");\n",
       "if(warn) {\n",
       "    warn.parentNode.removeChild(warn);\n",
       "}\n",
       "$3Dmolpromise.then(function() {\n",
       "viewer_17295394453724828 = $3Dmol.createViewer(document.getElementById(\"3dmolviewer_17295394453724828\"),{backgroundColor:\"white\"});\n",
       "viewer_17295394453724828.zoomTo();\n",
       "\tviewer_17295394453724828.addModel(\"@<TRIPOS>MOLECULE\\nr_binol\\n36 39 0 0 0\\nSMALL\\nNO_CHARGES\\n\\n@<TRIPOS>ATOM\\n1 None -2.9524 3.0000 0.0000 C\\n2 None -2.9524 1.5000 0.0000 C\\n3 None -1.6538 0.7500 0.0000 C\\n4 None -0.3538 1.5000 0.0000 C\\n5 None -0.3538 3.0000 0.0000 C\\n6 None -1.6538 3.7500 0.0000 C\\n7 None 0.9448 0.7500 1.0000 C\\n8 None 2.2434 1.5000 2.0000 C\\n9 None 2.2434 3.0000 2.0000 C\\n10 None 0.9448 3.7500 1.0000 C\\n11 None 0.9448 -0.7500 1.0000 C\\n12 None -0.3538 -1.5000 1.0000 C\\n13 None -0.3538 -3.0000 1.0000 C\\n14 None 0.9448 -3.7500 1.0000 C\\n15 None 2.2434 -3.0000 1.0000 C\\n16 None 2.2434 -1.5000 1.0000 C\\n17 None -1.6538 -0.7500 2.0000 C\\n18 None -2.9524 -1.5000 3.0000 C\\n19 None -2.9524 -3.0000 3.0000 C\\n20 None -1.6538 -3.7500 2.0000 C\\n21 None 3.5434 0.7500 2.0000 O\\n22 None 3.5434 -0.7500 1.0000 O\\n23 None -3.8790 3.5351 0.0000 H\\n24 None -3.8790 0.9649 0.0000 H\\n25 None -1.6548 -0.3200 0.0000 H\\n26 None -1.6548 4.8200 0.0000 H\\n27 None 3.0143 3.4452 2.5936 H\\n28 None 0.9448 4.8200 1.0000 H\\n29 None 0.9448 -4.8200 1.0000 H\\n30 None 3.1700 -3.5351 1.0000 H\\n31 None -1.6548 0.3200 2.0000 H\\n32 None -3.7233 -1.0548 3.5936 H\\n33 None -3.7233 -3.4452 3.5936 H\\n34 None -1.6548 -4.8200 2.0000 H\\n35 None 4.3663 0.2753 2.0000 H\\n36 None 4.3663 -0.2753 1.0000 H\\n@<TRIPOS>BOND\\n1 1 2 2\\n2 2 3 1\\n3 3 4 2\\n4 4 5 1\\n5 5 6 2\\n6 6 1 1\\n7 4 7 1\\n8 7 8 2\\n9 8 9 1\\n10 9 10 2\\n11 10 5 1\\n12 7 11 1\\n13 11 12 2\\n14 12 13 1\\n15 13 14 2\\n16 14 15 1\\n17 15 16 2\\n18 16 11 1\\n19 12 17 1\\n20 17 18 2\\n21 18 19 1\\n22 19 20 2\\n23 20 13 1\\n24 8 21 1\\n25 16 22 1\\n26 1 23 1\\n27 2 24 1\\n28 3 25 1\\n29 6 26 1\\n30 9 27 1\\n31 10 28 1\\n32 14 29 1\\n33 15 30 1\\n34 17 31 1\\n35 18 32 1\\n36 19 33 1\\n37 20 34 1\\n38 21 35 1\\n39 22 36 1\\n\\n\",\"mol2\");\n",
       "\tviewer_17295394453724828.setStyle({\"stick\": {\"radius\": 0.1}, \"sphere\": {\"scale\": 0.15}});\n",
       "\tviewer_17295394453724828.setHoverable({},true,\"\\n        function(atom,viewer,event,container) {\\n            if(!atom.label) {\\n                atom.label = viewer.addLabel(atom.elem + '(' + atom.index + ')', {position: atom, backgroundColor: 'silver', fontColor:'black'});\\n            }\\n        }\\n        \",\"\\n        function(atom,viewer) { \\n            if(atom.label) {\\n                viewer.removeLabel(atom.label);\\n                delete atom.label;\\n            }\\n        }\\n        \");\n",
       "\tviewer_17295394453724828.zoomTo();\n",
       "\tviewer_17295394453724828.setBackgroundColor(\"white\");\n",
       "viewer_17295394453724828.render();\n",
       "});\n",
       "</script>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/3dmoljs_load.v0": "<script>\n            $3Dmolpromise.then(function() { //wrap in promise for non-interactive functionality\n                \n                viewer_17295394453724828.render();\n            });\n            </script>",
      "text/html": [
       "<script>\n",
       "            $3Dmolpromise.then(function() { //wrap in promise for non-interactive functionality\n",
       "                \n",
       "                viewer_17295394453724828.render();\n",
       "            });\n",
       "            </script>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Molecule(name='r_binol', formula='C20 H14 O2')"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Reads CDXML File\n",
    "cdxf = ml.CDXMLFile(ml.files.parser_demo_cdxml)\n",
    "\n",
    "# Access molecule object\n",
    "ml_mol = cdxf['r_binol']\n",
    "\n",
    "# Adds implicit hydrogens\n",
    "ml_mol.add_implicit_hydrogens()\n",
    "ml_mol"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Structures can also be optimized using the `obabel_optimize` function. \n",
    "### Warning\n",
    "In certain cases, straight bonds parsed sometimes do not optimize. This can be fixed by doing a slight coordinate displacement. If you still experience problems with `openbabel` refusing to optimize the structures, do not forget to set the `BABEL_DATADIR` environment variable to point to a valid location with openbabel data files. With conda installations, it seems to be consistently pointing to `$CONDA_PREFIX/share/openbabel`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/3dmoljs_load.v0": "<div id=\"3dmolviewer_17295394458629186\"  style=\"position: relative; width: 100%; height: 500px;\">\n        <p id=\"3dmolwarning_17295394458629186\" style=\"background-color:#ffcccc;color:black\">You appear to be running in JupyterLab (or JavaScript failed to load for some other reason).  You need to install the 3dmol extension: <br>\n        <tt>jupyter labextension install jupyterlab_3dmol</tt></p>\n        </div>\n<script>\n\nvar loadScriptAsync = function(uri){\n  return new Promise((resolve, reject) => {\n    //this is to ignore the existence of requirejs amd\n    var savedexports, savedmodule;\n    if (typeof exports !== 'undefined') savedexports = exports;\n    else exports = {}\n    if (typeof module !== 'undefined') savedmodule = module;\n    else module = {}\n\n    var tag = document.createElement('script');\n    tag.src = uri;\n    tag.async = true;\n    tag.onload = () => {\n        exports = savedexports;\n        module = savedmodule;\n        resolve();\n    };\n  var firstScriptTag = document.getElementsByTagName('script')[0];\n  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n});\n};\n\nif(typeof $3Dmolpromise === 'undefined') {\n$3Dmolpromise = null;\n  $3Dmolpromise = loadScriptAsync('https://cdnjs.cloudflare.com/ajax/libs/3Dmol/2.0.4/3Dmol-min.js');\n}\n\nvar viewer_17295394458629186 = null;\nvar warn = document.getElementById(\"3dmolwarning_17295394458629186\");\nif(warn) {\n    warn.parentNode.removeChild(warn);\n}\n$3Dmolpromise.then(function() {\nviewer_17295394458629186 = $3Dmol.createViewer(document.getElementById(\"3dmolviewer_17295394458629186\"),{backgroundColor:\"white\"});\nviewer_17295394458629186.zoomTo();\n\tviewer_17295394458629186.addModel(\"@<TRIPOS>MOLECULE\\nr_binol\\n36 39 0 0 0\\nSMALL\\nNO_CHARGES\\n\\n@<TRIPOS>ATOM\\n1 None -1.9882 3.6210 -0.1591 C\\n2 None -1.9339 2.2435 -0.3081 C\\n3 None -0.8913 1.5219 0.2780 C\\n4 None 0.1205 2.1448 1.0523 C\\n5 None 0.0595 3.5612 1.1614 C\\n6 None -0.9916 4.2748 0.5615 C\\n7 None 1.1711 1.4321 1.7246 C\\n8 None 2.1561 2.1873 2.3965 C\\n9 None 2.0933 3.5730 2.4808 C\\n10 None 1.0445 4.2534 1.8753 C\\n11 None 1.1988 -0.0662 1.7544 C\\n12 None 0.1615 -0.8251 2.3912 C\\n13 None 0.1678 -2.2416 2.2769 C\\n14 None 1.2124 -2.8865 1.6036 C\\n15 None 2.2558 -2.1606 1.0405 C\\n16 None 2.2406 -0.7714 1.1155 C\\n17 None -0.8983 -0.2488 3.1353 C\\n18 None -1.9276 -1.0173 3.6837 C\\n19 None -1.9201 -2.3949 3.5243 C\\n20 None -0.8730 -3.0024 2.8354 C\\n21 None 3.2476 1.6121 2.9941 O\\n22 None 3.2986 -0.0715 0.5929 O\\n23 None -2.7998 4.1879 -0.6064 H\\n24 None -2.7011 1.7228 -0.8746 H\\n25 None -0.8846 0.4440 0.1274 H\\n26 None -1.0456 5.3577 0.6577 H\\n27 None 2.8668 4.1198 3.0124 H\\n28 None 1.0109 5.3377 1.9569 H\\n29 None 1.2293 -3.9723 1.5272 H\\n30 None 3.0687 -2.6926 0.5563 H\\n31 None -0.9386 0.8278 3.2938 H\\n32 None -2.7321 -0.5325 4.2304 H\\n33 None -2.7220 -2.9973 3.9420 H\\n34 None -0.8788 -4.0861 2.7342 H\\n35 None 3.4599 0.8234 2.4603 H\\n36 None 3.8095 -0.6597 0.0108 H\\n@<TRIPOS>BOND\\n1 1 2 2\\n2 2 3 1\\n3 3 4 2\\n4 4 5 1\\n5 5 6 2\\n6 6 1 1\\n7 4 7 1\\n8 7 8 2\\n9 8 9 1\\n10 9 10 2\\n11 10 5 1\\n12 7 11 1\\n13 11 12 2\\n14 12 13 1\\n15 13 14 2\\n16 14 15 1\\n17 15 16 2\\n18 16 11 1\\n19 12 17 1\\n20 17 18 2\\n21 18 19 1\\n22 19 20 2\\n23 20 13 1\\n24 8 21 1\\n25 16 22 1\\n26 1 23 1\\n27 2 24 1\\n28 3 25 1\\n29 6 26 1\\n30 9 27 1\\n31 10 28 1\\n32 14 29 1\\n33 15 30 1\\n34 17 31 1\\n35 18 32 1\\n36 19 33 1\\n37 20 34 1\\n38 21 35 1\\n39 22 36 1\\n\\n\",\"mol2\");\n\tviewer_17295394458629186.setStyle({\"stick\": {\"radius\": 0.1}, \"sphere\": {\"scale\": 0.15}});\n\tviewer_17295394458629186.setHoverable({},true,\"\\n        function(atom,viewer,event,container) {\\n            if(!atom.label) {\\n                atom.label = viewer.addLabel(atom.elem + '(' + atom.index + ')', {position: atom, backgroundColor: 'silver', fontColor:'black'});\\n            }\\n        }\\n        \",\"\\n        function(atom,viewer) { \\n            if(atom.label) {\\n                viewer.removeLabel(atom.label);\\n                delete atom.label;\\n            }\\n        }\\n        \");\n\tviewer_17295394458629186.zoomTo();\n\tviewer_17295394458629186.setBackgroundColor(\"white\");\nviewer_17295394458629186.render();\n});\n</script>",
      "text/html": [
       "<div id=\"3dmolviewer_17295394458629186\"  style=\"position: relative; width: 100%; height: 500px;\">\n",
       "        <p id=\"3dmolwarning_17295394458629186\" style=\"background-color:#ffcccc;color:black\">You appear to be running in JupyterLab (or JavaScript failed to load for some other reason).  You need to install the 3dmol extension: <br>\n",
       "        <tt>jupyter labextension install jupyterlab_3dmol</tt></p>\n",
       "        </div>\n",
       "<script>\n",
       "\n",
       "var loadScriptAsync = function(uri){\n",
       "  return new Promise((resolve, reject) => {\n",
       "    //this is to ignore the existence of requirejs amd\n",
       "    var savedexports, savedmodule;\n",
       "    if (typeof exports !== 'undefined') savedexports = exports;\n",
       "    else exports = {}\n",
       "    if (typeof module !== 'undefined') savedmodule = module;\n",
       "    else module = {}\n",
       "\n",
       "    var tag = document.createElement('script');\n",
       "    tag.src = uri;\n",
       "    tag.async = true;\n",
       "    tag.onload = () => {\n",
       "        exports = savedexports;\n",
       "        module = savedmodule;\n",
       "        resolve();\n",
       "    };\n",
       "  var firstScriptTag = document.getElementsByTagName('script')[0];\n",
       "  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n",
       "});\n",
       "};\n",
       "\n",
       "if(typeof $3Dmolpromise === 'undefined') {\n",
       "$3Dmolpromise = null;\n",
       "  $3Dmolpromise = loadScriptAsync('https://cdnjs.cloudflare.com/ajax/libs/3Dmol/2.0.4/3Dmol-min.js');\n",
       "}\n",
       "\n",
       "var viewer_17295394458629186 = null;\n",
       "var warn = document.getElementById(\"3dmolwarning_17295394458629186\");\n",
       "if(warn) {\n",
       "    warn.parentNode.removeChild(warn);\n",
       "}\n",
       "$3Dmolpromise.then(function() {\n",
       "viewer_17295394458629186 = $3Dmol.createViewer(document.getElementById(\"3dmolviewer_17295394458629186\"),{backgroundColor:\"white\"});\n",
       "viewer_17295394458629186.zoomTo();\n",
       "\tviewer_17295394458629186.addModel(\"@<TRIPOS>MOLECULE\\nr_binol\\n36 39 0 0 0\\nSMALL\\nNO_CHARGES\\n\\n@<TRIPOS>ATOM\\n1 None -1.9882 3.6210 -0.1591 C\\n2 None -1.9339 2.2435 -0.3081 C\\n3 None -0.8913 1.5219 0.2780 C\\n4 None 0.1205 2.1448 1.0523 C\\n5 None 0.0595 3.5612 1.1614 C\\n6 None -0.9916 4.2748 0.5615 C\\n7 None 1.1711 1.4321 1.7246 C\\n8 None 2.1561 2.1873 2.3965 C\\n9 None 2.0933 3.5730 2.4808 C\\n10 None 1.0445 4.2534 1.8753 C\\n11 None 1.1988 -0.0662 1.7544 C\\n12 None 0.1615 -0.8251 2.3912 C\\n13 None 0.1678 -2.2416 2.2769 C\\n14 None 1.2124 -2.8865 1.6036 C\\n15 None 2.2558 -2.1606 1.0405 C\\n16 None 2.2406 -0.7714 1.1155 C\\n17 None -0.8983 -0.2488 3.1353 C\\n18 None -1.9276 -1.0173 3.6837 C\\n19 None -1.9201 -2.3949 3.5243 C\\n20 None -0.8730 -3.0024 2.8354 C\\n21 None 3.2476 1.6121 2.9941 O\\n22 None 3.2986 -0.0715 0.5929 O\\n23 None -2.7998 4.1879 -0.6064 H\\n24 None -2.7011 1.7228 -0.8746 H\\n25 None -0.8846 0.4440 0.1274 H\\n26 None -1.0456 5.3577 0.6577 H\\n27 None 2.8668 4.1198 3.0124 H\\n28 None 1.0109 5.3377 1.9569 H\\n29 None 1.2293 -3.9723 1.5272 H\\n30 None 3.0687 -2.6926 0.5563 H\\n31 None -0.9386 0.8278 3.2938 H\\n32 None -2.7321 -0.5325 4.2304 H\\n33 None -2.7220 -2.9973 3.9420 H\\n34 None -0.8788 -4.0861 2.7342 H\\n35 None 3.4599 0.8234 2.4603 H\\n36 None 3.8095 -0.6597 0.0108 H\\n@<TRIPOS>BOND\\n1 1 2 2\\n2 2 3 1\\n3 3 4 2\\n4 4 5 1\\n5 5 6 2\\n6 6 1 1\\n7 4 7 1\\n8 7 8 2\\n9 8 9 1\\n10 9 10 2\\n11 10 5 1\\n12 7 11 1\\n13 11 12 2\\n14 12 13 1\\n15 13 14 2\\n16 14 15 1\\n17 15 16 2\\n18 16 11 1\\n19 12 17 1\\n20 17 18 2\\n21 18 19 1\\n22 19 20 2\\n23 20 13 1\\n24 8 21 1\\n25 16 22 1\\n26 1 23 1\\n27 2 24 1\\n28 3 25 1\\n29 6 26 1\\n30 9 27 1\\n31 10 28 1\\n32 14 29 1\\n33 15 30 1\\n34 17 31 1\\n35 18 32 1\\n36 19 33 1\\n37 20 34 1\\n38 21 35 1\\n39 22 36 1\\n\\n\",\"mol2\");\n",
       "\tviewer_17295394458629186.setStyle({\"stick\": {\"radius\": 0.1}, \"sphere\": {\"scale\": 0.15}});\n",
       "\tviewer_17295394458629186.setHoverable({},true,\"\\n        function(atom,viewer,event,container) {\\n            if(!atom.label) {\\n                atom.label = viewer.addLabel(atom.elem + '(' + atom.index + ')', {position: atom, backgroundColor: 'silver', fontColor:'black'});\\n            }\\n        }\\n        \",\"\\n        function(atom,viewer) { \\n            if(atom.label) {\\n                viewer.removeLabel(atom.label);\\n                delete atom.label;\\n            }\\n        }\\n        \");\n",
       "\tviewer_17295394458629186.zoomTo();\n",
       "\tviewer_17295394458629186.setBackgroundColor(\"white\");\n",
       "viewer_17295394458629186.render();\n",
       "});\n",
       "</script>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/3dmoljs_load.v0": "<script>\n            $3Dmolpromise.then(function() { //wrap in promise for non-interactive functionality\n                \n                viewer_17295394458629186.render();\n            });\n            </script>",
      "text/html": [
       "<script>\n",
       "            $3Dmolpromise.then(function() { //wrap in promise for non-interactive functionality\n",
       "                \n",
       "                viewer_17295394458629186.render();\n",
       "            });\n",
       "            </script>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Molecule(name='r_binol', formula='C20 H14 O2')"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Optimizes the structure\n",
    "mob.obabel_optimize(\n",
    "    ml_mol,\n",
    "    ff = \"MMFF94\",\n",
    "    max_steps = 1000,\n",
    "    inplace=True,\n",
    "    coord_displace=True #Sometimes necessary to get flat bonds/structures to correctly relax\n",
    ")\n",
    "ml_mol"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Multi-Attachment Optimization from CDXML File\n",
    "\n",
    "`molli` has also introduced a prototype optimization function `optimize_coordination`, that has been successfully tested with a few different structures. It has run into some issues with Linux and Mac operating systems, but has shown greater success on Windows. It is available in the `openbabel` interface within `molli`, but due to the problems on varying OS, it is not fully illustrated in this example.\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "dev-blake",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
